package com.zbl.zblproject.erp.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.zbl.zblproject.core.entity.AdminUser;
import com.zbl.zblproject.core.entity.Order;
import com.zbl.zblproject.core.entity.Result;
import com.zbl.zblproject.core.mapper.AdminUserMapper;
import com.zbl.zblproject.core.mapper.OrderItemMapper;
import com.zbl.zblproject.core.utils.ResultUtil;
import com.zbl.zblproject.erp.entity.*;
import com.zbl.zblproject.erp.mapper.ErpGoodMapper;
import com.zbl.zblproject.erp.mapper.ErpRemoteOrderMapper;
import com.zbl.zblproject.erp.service.ErpOrderService;
import com.zbl.zblproject.erp.utils.ErpOrderFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.validation.constraints.Min;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;


/**
 * @author youlanqiang
 * @version 1.0
 * @date 2018/10/10
 * 出入库操作接口
 */
@RestController
@Api(value = "出入库操作接口", tags = {"出入库操作接口"})
@RequestMapping("/erp-order")
public class ErpOrderController {


    /**
     * 入库单/欠货
     */
    public static int MODE_IN = 0;

    /**
     * 出库单/缺货
     */
    public static int MODE_OUT = 1;

    /**
     * 退货单
     */
    public static int MODE_RETURN = 2;

    private static Logger logger = LoggerFactory.getLogger(ErpOrderController.class);


    @Value("${img-path}")
    private String imgPath;

    @Value("${remote-url}")
    private String remoteUrl;

    @Autowired
    private ErpOrderService erpOrderService;

    @Autowired
    private AdminUserMapper userMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private ErpRemoteOrderMapper erpRemoteOrderMapper;

    @Autowired
    private ErpGoodMapper goodMapper;



    @GetMapping("/ended-erp/{orderSn}")
    @ApiOperation("删除对应ERP订单")
    public Result endedErpOrder(@ApiParam("订单号") @PathVariable String orderSn) {
        if (erpOrderService.deleteErpOrder(orderSn)) {
            return ResultUtil.success("订单删除成功!");
        }
        return ResultUtil.error("订单删除失败!");
    }

    @GetMapping("/ended-owe/{orderSn}")
    @ApiOperation("终结欠货订单")
    public Result endedOweOrder(@ApiParam("订单号") @PathVariable String orderSn) {
        if (erpOrderService.endedOwe(orderSn)) {
            return ResultUtil.success("终结成功!");
        }
        return ResultUtil.error("终结失败!");
    }


    @PostMapping("/update-context/{orderSn}")
    @ApiOperation("更新订单备注")
    public Result updateOrderContext(@ApiParam("订单号") @PathVariable String orderSn,
                                     @ApiParam("备注信息") @RequestParam("context") String context) {
        if (erpOrderService.updateErpOrderByContext(orderSn, context)) {
            return ResultUtil.success("更新成功!");
        }
        return ResultUtil.error("更新失败!");
    }

    @GetMapping("/get-context/{orderSn}")
    @ApiOperation("获取订单备注")
    public Result getOrderContext(@ApiParam("订单号") @PathVariable String orderSn) {
        ErpOrder order = erpOrderService.getErpOrder(orderSn);
        if (order == null) {
            return ResultUtil.error("没有该订单号.");
        }
        return ResultUtil.success("成功.", order.getContext());
    }

    @GetMapping("/rollback/{orderInfo}")
    @ApiOperation("订单状态回滚")
    public Result rollback(@ApiParam("订单号") @PathVariable String orderInfo) {
        try {
            if (erpOrderService.rollbackOrder(orderInfo)) {
                return ResultUtil.success("回滚成功!");
            } else {
                return ResultUtil.error("回滚失败!");
            }
        } catch (Exception e) {
            return ResultUtil.error(e.getMessage());
        }
    }

    @GetMapping("/pass/{orderInfo}")
    @ApiOperation("订单状态通过")
    public Result pass(@ApiParam("订单号") @PathVariable String orderInfo,
                       @ApiParam("客户ID") @RequestParam("userId") Integer userId) {
        try {
            synchronized (ErpOrderController.class) {
                ErpOrder order = erpOrderService.passOrder(orderInfo, userId);
                return ResultUtil.success("成功!", order);
            }
        } catch (RuntimeException e) {
            e.printStackTrace();
            return ResultUtil.error(e.getMessage());
        }
    }


    @PostMapping("/addin/{orderNo}/{status}")
    @ApiOperation("添加入库单附带状态")
    public Result addInOrderAndStatus(@ApiParam("订单号") @PathVariable String orderNo,
                                      @ApiParam("用户ID") @RequestParam("userId") Integer userId,
                                      @ApiParam("工厂名称") @RequestParam("name") String name,
                                      @ApiParam("供应商名称") @RequestParam("suppliersName") String suppliersName,
                                      @ApiParam("供应商ID") @RequestParam("suppliersId") String suppliersId,
                                      @ApiParam("远程订单号") @RequestParam("orders") String orders,
                                      @ApiParam("订单状态") @PathVariable Integer status,
                                      @ApiParam("订单商品") @RequestParam("items") String json) {

        logger.info("/addin/{orderNo}>>>suppliersName:"+suppliersName);
        logger.info("/addin/{orderNo}>>>suppliersId:"+suppliersId);

        Result result = addOrderAndStatus(orderNo, userId, status, json, MODE_IN, 0, "", name, "",suppliersName,suppliersId);
        if (result.getCode() == 200) {
            List<String> resultOrder = JSONArray.parseArray(orders, String.class);
            for (String remoteOrder : resultOrder) {
                ErpRemoteOrder order = new ErpRemoteOrder();
                //获取对应远程订单的CGDD订单号
                try {
                    RestTemplate restTemplate = new RestTemplate();
                    Result remoteResult = restTemplate.getForObject(remoteUrl + "/order/remote-origin/" + remoteOrder, Result.class);
                    if(remoteResult.getCode() == 200){
                        order.setOriginOrder(remoteResult.getData().toString());
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
                order.setLocalOrder(orderNo);
                order.setRemoteOrder(remoteOrder);
                order.setStatus(0);
                erpRemoteOrderMapper.insert(order);
            }
        }
        return result;
    }

    @PostMapping("/addreturn/{orderNo}/{status}")
    @ApiOperation("添加退货库单附带状态")
    public Result addReturnOrder(@ApiParam("订单号") @PathVariable String orderNo,
                                 @ApiParam("用户ID") @RequestParam("userId") Integer userId,
                                 @ApiParam("工厂名称") @RequestParam("name") String name,
                                 @ApiParam("订单状态") @PathVariable Integer status,
                                 @ApiParam("订单商品") @RequestParam("items") String json) {
        return addOrderAndStatus("THD" + Instant.now().toEpochMilli(), userId, status, json, MODE_RETURN, 0, orderNo, name, "","","");
    }


    @PostMapping("/addout/{orderNo}/{status}")
    @ApiOperation("添加出库单附带状态")
    public Result addOutOrderAndStatus(@ApiParam("订单号") @PathVariable String orderNo,
                                       @ApiParam("店家ID") @RequestParam("storeId") Integer storeId,
                                       @ApiParam("原始订单号") @RequestParam("originOrder") String originOrder,
                                       @ApiParam("客户ID") @RequestParam("userId") Integer userId,
                                       @ApiParam("订单状态") @PathVariable Integer status,
                                       @ApiParam("订单备注") @RequestParam("context") String context,
                                       @ApiParam("订单商品") @RequestParam("items") String json) {


        return addOrderAndStatus(orderNo, userId, status, json, MODE_OUT, storeId, originOrder, null, context,"","");

    }

    @GetMapping("/rk-back/{orderSn}")
    @ApiOperation("入库单从已完成回滚到草稿")
    public Result intoWarehouseOrderBack(@ApiParam("订单号") @PathVariable String orderSn) {
        try {
            if (erpOrderService.rkBack(orderSn)) {
                return ResultUtil.success("订单号回滚成功");
            }
            return ResultUtil.error("订单号回滚失败");
        } catch (RuntimeException e) {
            return ResultUtil.error(e.getMessage());
        }
    }


    private Result addOrderAndStatus(String orderNo, Integer userId, Integer status, String json, int mode,
                                     Integer storeId, String originOrderSn, String searchName, String context,String spName,String spID) {

        try {
            //1.1遍历json
            //1.1 goodId  去zbl_gooods 查询  并且 supplresid

            AdminUser user = getUserById(userId);
            ErpOrder order = ErpOrderFactory.createOrder(orderNo,
                    user.getUserName(), mode);
            order.setStoreId(storeId);
            if (!Strings.isNullOrEmpty(searchName)) {
                order.setSearchName(searchName);
            } else if (storeId != 0) {
                AdminUser store = getUserById(storeId);
                order.setSearchName(store.getUserName());
            }
            order.setContext(context);
            order.setOriginOrderSn(originOrderSn);

            order.setSupplierName(spName);//放供应商名称

            List<ErpOrderItem> erpOrderItems = parseErpOrderItems(json);

//            if(null!=erpOrderItems&&!erpOrderItems.isEmpty()){
//                for(ErpOrderItem eit:erpOrderItems){
//                    logger.info("erpOrderItems>getGoodsId="+eit.getGoodsId());
//                    int goodsid=eit.getGoodsId();
//                    int spid=goodMapper.selectSupplierById(goodsid);//gooods 供应商主键
//                    int cjl=Integer.valueOf(spID);
//                    if(spid!=cjl){
//                        logger.info("如果传进来的供应商主键  和 goods表里查询的供应商主键 不一样 就更新");
//                        //如果传进来的供应商主键  和 goods表里查询的供应商主键 不一样 就更新
//                        int i=goodMapper.updateSuppliersByGoodsId(goodsid,cjl);
//                        System.out.println("如果传进来的供应商主键  和 goods表里查询的供应商主键="+i);
//                    }
//
//                    if (order.getMode() == MODE_RETURN) {
//                        int goodsPrice=eit.getGoodsPrice().intValue();
//                        //查询order中的金额
//                        BigDecimal b=goodMapper.getshoPriceByGoodsId(goodsid);
//                        if(goodsPrice!=b.intValue()){
//                            //更新价格
//                            int i=goodMapper.updateSuppliersJG(goodsPrice,goodsid);
//                        }
//                    }
//                }
//
//            }


            //suppliersId
            if (order.getMode() == MODE_IN) {
                ErpOrderItem item = erpOrderItems.get(0);
                if (item.getOrderItemId() != 0) {
                    order.setOriginOrderSn(orderItemMapper.selectOrderSn(item.getOrderItemId()));
                }
                if (status != ErpOrderStatus.draft.getStatus()
                        && status != ErpOrderStatus.submit.getStatus()) {
                    return ResultUtil.error("失败", "状态只能是草稿或提交!");
                }
            } else if (order.getMode() == MODE_OUT) {
                if (status != ErpOrderStatus.draft.getStatus()
                        && status != ErpOrderStatus.submit.getStatus() &&
                        status != ErpOrderStatus.finance.getStatus()) {
                    return ResultUtil.error("失败", "状态只能是草稿或提交!");
                }
            } else {
                throw new RuntimeException("没有这个订单类型");
            }
            order.setStatus(status);
            order = erpOrderService.createErpOrder(order, erpOrderItems);
            return ResultUtil.success("创建成功!", order);
        } catch (RuntimeException e) {
            logger.warn(e.getMessage());
            return ResultUtil.error(e.getMessage());
        }
    }


    @PostMapping("/addin/{orderNo}")
    @ApiOperation("添加入库单")
    public Result addInOrder(@ApiParam("订单号") @PathVariable String orderNo,
                             @ApiParam("远程订单号") @RequestParam("orders") String orders,
                             @ApiParam("用户ID") @RequestParam("userId") Integer userId,
                             @ApiParam("订单商品") @RequestParam("items") String json) {
        Result result = addOrderAndStatus(orderNo, userId, 0, json, MODE_IN, 0, "", "", "","","");
        if (result.getCode() == 200) {
            List<String> resultOrder = JSONArray.parseArray(orders, String.class);
            for (String remoteOrder : resultOrder) {
                ErpRemoteOrder order = new ErpRemoteOrder();
                //获取对应远程订单的CGDD订单号
                try {
                    RestTemplate restTemplate = new RestTemplate();
                    Result remoteResult = restTemplate.getForObject(remoteUrl + "/order/remote-origin/" + remoteOrder, Result.class);
                    if(remoteResult.getCode() == 200){
                        order.setOriginOrder(remoteResult.getData().toString());
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
                order.setLocalOrder(orderNo);
                order.setRemoteOrder(remoteOrder);
                order.setStatus(0);
                erpRemoteOrderMapper.insert(order);
            }
        }
        return result;
    }


    @PostMapping("/addout/{orderNo}")
    @ApiOperation("添加出库单")
    public Result addOutOrder(@ApiParam("订单号") @PathVariable String orderNo,
                              @ApiParam("店家ID") @RequestParam("storeId") Integer storeId,
                              @ApiParam("原始订单号") @RequestParam("originOrder") String originOrder,
                              @ApiParam("客户ID") @RequestParam("userId") Integer userId,
                              @ApiParam("订单备注") @RequestParam("context") String context,
                              @ApiParam("订单商品") @RequestParam("items") String json) {
        //出库提交之后默认财务审核
        return addOrderAndStatus(orderNo, userId, ErpOrderStatus.finance.getStatus(), json, MODE_OUT, storeId, originOrder, "", context,"","");
    }

    @GetMapping("/inlist/{current}/{size}")
    @ApiOperation("入库订单列表查询")
    public Result listByIn(@ApiParam("查询页数") @PathVariable int current,
                           @ApiParam("查询数量") @PathVariable int size,
                           @ApiParam("查询订单号") @RequestParam("search") String search,
                           @ApiParam("起始时间") @RequestParam("start") String start,
                           @ApiParam("结束时间") @RequestParam("end") String end,
                           @ApiParam("查询用户姓名") @RequestParam("user") String user,
                           @ApiParam("查询对应名称") @RequestParam("name") String name,
                           @ApiParam("查询状态 -1 为查询全部") @RequestParam("status") int status,
                           @ApiParam("查询品牌名称") @RequestParam("brandName") String brandName) {

        String searchStr = searchStr(search, start, end, user, status, MODE_IN, name, brandName);
        IPage<ErpOrder> orders = erpOrderService.erpOrderList(searchStr, current, size);
        return ResultUtil.success("成功", orders);
    }

    @GetMapping("/outlist/{current}/{size}")
    @ApiOperation("出库订单列表查询")
    public Result listByOut(@ApiParam("查询页数") @PathVariable int current,
                            @ApiParam("查询数量") @PathVariable int size,
                            @ApiParam("查询订单号") @RequestParam("search") String search,
                            @ApiParam("起始时间") @RequestParam("start") String start,
                            @ApiParam("结束时间") @RequestParam("end") String end,
                            @ApiParam("查询对应名称") @RequestParam("name") String name,
                            @ApiParam("查询用户姓名") @RequestParam("user") String user,
                            @ApiParam("品牌名称") @RequestParam("brandName") String brandName,
                            @ApiParam("查询状态 -1 为查询全部") @RequestParam("status") int status) {


        String searchStr = searchStr(search, start, end, user, status, MODE_OUT, name, brandName);

        IPage<ErpOrder> orders = erpOrderService.erpOrderList(searchStr, current, size);
        return ResultUtil.success("成功", orders);
    }


    @GetMapping("/itemlist/{orderInfo}")
    @ApiOperation("获取订单的货品单")
    public Result listByItem(@ApiParam("订单号") @PathVariable String orderInfo) {
        try {
            List<ErpTempOrderItem> items = erpOrderService.getOrderItemByOrderNotDesc(orderInfo);
            ErpOrder order = erpOrderService.getErpOrder(orderInfo);
            return ResultUtil.success("成功!", items).setAnother(order);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(e.getMessage());
        }
    }

    @GetMapping("/itemlist-desc/{orderInfo}")
    @ApiOperation("获取订单的货品单")
    public Result listByItemDesc(@ApiParam("订单号") @PathVariable String orderInfo) {
        try {
            List<ErpTempOrderItem> items = erpOrderService.getOrderItemByOrder(orderInfo);
            return ResultUtil.success("成功!", items);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(e.getMessage());
        }
    }

    @DeleteMapping("/order/{id}")
    @ApiOperation("删除出入库订单")
    public Result deleteOrder(@ApiParam("订单ID") @Min(value = 1, message = "订单ID异常") @PathVariable Integer id) {

        if (erpOrderService.deleteOrder(id)) {
            return ResultUtil.success("删除成功!");
        }

        return ResultUtil.error("删除失败!");
    }

    @GetMapping("/remote-out/{id}")
    @ApiOperation("获取远程出库单")
    public Result remoteOut(@ApiParam("用户ID") @PathVariable int id) {

        try {
            AdminUser adminUser = userMapper.selectById(id);
            if (adminUser == null) {
                return ResultUtil.error("没有发现该用户!");
            }
            List<Order> orders =  erpOrderService.remoteOrders(adminUser);
            return ResultUtil.success("成功!", orders);
        } catch (RuntimeException e) {
            return ResultUtil.error(e.getMessage());
        }
    }


    /**
     * 拼接查询字符串
     *
     * @param search 查询条件
     * @param start  开始时间
     * @param end    结束时间
     * @param user   用户名
     * @param status 状态
     * @return
     */
    private String searchStr(String search, String start, String end, String user, int status, int mode, String name, String brandName) {
        StringBuffer buffer = new StringBuffer();
        buffer.append(" WHERE ");

        buffer.append(" DATE_FORMAT(create_time, '%Y-%m-%d') >= ");
        buffer.append("'").append(start).append("'");
        buffer.append(" AND ");
        buffer.append(" DATE_FORMAT(create_time, '%Y-%m-%d') <= ");
        buffer.append("'").append(end).append("'");

        if (!Strings.isNullOrEmpty(search.trim())) {
            buffer.append(" AND");
            buffer.append(" order_info LIKE '%");
            buffer.append(search);
            buffer.append("%' ");
        }
        if (!Strings.isNullOrEmpty(user.trim())) {
            buffer.append(" AND");
            buffer.append(" operator LIKE '%");
            buffer.append(user);
            buffer.append("%' ");
        }
        if (!Strings.isNullOrEmpty(name.trim())) {
            buffer.append(" AND");
            if (mode == MODE_IN) {
                buffer.append(" supplier_name LIKE '%");
                buffer.append(name);
                buffer.append("%' ");
            } else {
                buffer.append(" search_name LIKE '%");
                buffer.append(name);
                buffer.append("%' ");
            }
        }
        if (!Strings.isNullOrEmpty(brandName.trim())) {
            buffer.append(" AND");
            buffer.append(" brand_name LIKE '%");
            buffer.append(brandName);
            buffer.append("%' ");
        }
        if (status == -1) {
            buffer.append(" AND mode = ").append(mode);
        } else {
            buffer.append(" AND");
            buffer.append(" status = ").append(status).append(" AND mode = ").append(mode);
        }
        logger.info("条件语句: " + buffer.toString());
        return buffer.toString();
    }

    private AdminUser getUserById(int id) {
        AdminUser user = userMapper.selectById(id);
        Preconditions.checkNotNull(user, "未发现对应的用户");
        if (user.getStatus() != 0) {
            throw new RuntimeException("用户未被启用");
        }
        return user;
    }


    private List<ErpOrderItem> parseErpOrderItems(String json) {
        //  logger.info("JSON信息:" + json);
        JSONArray array = JSONArray.parseArray(json);
        List<ErpOrderItem> items = new ArrayList<>(array.size());
        JSONObject object;
        ErpOrderItem orderItem;
        for (int i = 0; i < array.size(); i++) {
            object = array.getJSONObject(i);
            orderItem = new ErpOrderItem();
            orderItem.setGoodsId(object.getInteger("goodsId"));
            orderItem.setGoodsList(4);

            orderItem.setGoodsNum(object.getInteger("goodsNum"));
            orderItem.setGoodsPrice(object.getBigDecimal("goodsPrice"));

            Integer id = object.getInteger("id");
            if (id == null) {
                orderItem.setId(0);
            } else {
                orderItem.setId(object.getInteger("id"));
            }
            //orderItemId
            if (object.containsKey("orderItemId")) {
                orderItem.setOrderItemId(object.getInteger("orderItemId"));
            }
            if (object.containsKey("oweNum")) {
                orderItem.setOweNum(object.getInteger("oweNum"));
            }
            if (object.containsKey("isGive")) {
                orderItem.setIsGive(object.getInteger("isGive"));
            }
            if (object.containsKey("oweItem")) {
                orderItem.setOweItem(object.getInteger("oweItem"));
            }

            items.add(orderItem);
        }
        return items;
    }

}
